Allow choosing a layout of diagrams generated by Graphviz

Akinori MUSHA 8 years ago
parent
commit
8b4907165f

+ 6 - 0
.env.example

@@ -167,6 +167,12 @@ EVENT_EXPIRATION_CHECK=6h
167 167
 # enabled.
168 168
 #USE_GRAPHVIZ_DOT=dot
169 169
 
170
+# Default layout for agent flow diagrams generated by Graphviz.
171
+# Choose from `circo`, `dot` (default), `fdp`, `neato`, `osage`,
172
+# `patchwork`, `sfdp`, or `twopi`.  Note that not all layouts are
173
+# supported by Graphviz depending on the build options.
174
+#DIAGRAM_DEFAULT_LAYOUT=dot
175
+
170 176
 # Timezone. Use `rake time:zones:local` or `rake time:zones:all` to get your zone name
171 177
 TIMEZONE="Pacific Time (US & Canada)"
172 178
 

+ 1 - 0
app/assets/javascripts/diagram.js.coffee

@@ -3,6 +3,7 @@
3 3
 $ ->
4 4
   svg = document.querySelector('.agent-diagram svg.diagram')
5 5
   overlay = document.querySelector('.agent-diagram .overlay')
6
+  $(overlay).width($(svg).width()).height($(svg).height())
6 7
   getTopLeft = (node) ->
7 8
     bbox = node.getBBox()
8 9
     point = svg.createSVGPoint()

+ 7 - 5
app/helpers/dot_helper.rb

@@ -1,8 +1,8 @@
1 1
 module DotHelper
2
-  def render_agents_diagram(agents)
2
+  def render_agents_diagram(agents, layout: nil)
3 3
     if (command = ENV['USE_GRAPHVIZ_DOT']) &&
4 4
        (svg = IO.popen([command, *%w[-Tsvg -q1 -o/dev/stdout /dev/stdin]], 'w+') { |dot|
5
-          dot.print agents_dot(agents, true)
5
+          dot.print agents_dot(agents, rich: true, layout: layout)
6 6
           dot.close_write
7 7
           dot.read
8 8
         } rescue false)
@@ -125,7 +125,7 @@ module DotHelper
125 125
     DotDrawer.draw(vars, &block)
126 126
   end
127 127
 
128
-  def agents_dot(agents, rich = false)
128
+  def agents_dot(agents, rich: false, layout: nil)
129 129
     draw(agents: agents,
130 130
          agent_id: ->agent { 'a%d' % agent.id },
131 131
          agent_label: ->agent {
@@ -158,7 +158,10 @@ module DotHelper
158 158
       end
159 159
 
160 160
       block('digraph', 'Agent Event Flow') {
161
-        # statement 'graph', rankdir: 'LR'
161
+        layout ||= ENV['DIAGRAM_DEFAULT_LAYOUT'].presence
162
+        if rich && /\A[a-z]+\z/ === layout
163
+          statement 'graph', layout: layout, overlap: 'false'
164
+        end
162 165
         statement 'node',
163 166
                   shape: 'box',
164 167
                   style: 'rounded',
@@ -197,7 +200,6 @@ module DotHelper
197 200
       root << svg
198 201
       root << overlay_container = Nokogiri::XML::Node.new('div', doc) { |div|
199 202
         div['class'] = 'overlay-container'
200
-        div['style'] = "width: #{svg['width']}; height: #{svg['height']}"
201 203
       }
202 204
       overlay_container << overlay = Nokogiri::XML::Node.new('div', doc) { |div|
203 205
         div['class'] = 'overlay'

+ 1 - 1
app/views/diagrams/show.html.erb

@@ -20,7 +20,7 @@
20 20
       </div>
21 21
 
22 22
       <div class='digraph'>
23
-        <%= render_agents_diagram(@agents) %>
23
+        <%= render_agents_diagram(@agents, layout: params[:layout]) %>
24 24
       </div>
25 25
     </div>
26 26
   </div>

+ 1 - 1
spec/helpers/dot_helper_spec.rb

@@ -72,7 +72,7 @@ describe DotHelper do
72 72
       end
73 73
 
74 74
       it "generates a richer DOT script" do
75
-        expect(agents_dot(@agents, true)).to match(%r{
75
+        expect(agents_dot(@agents, rich: true)).to match(%r{
76 76
           \A
77 77
           digraph \x20 "Agent \x20 Event \x20 Flow" \{
78 78
             node \[ [^\]]+ \];